package com.shop2cn.iapi.sqoptrade.testcase;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.google.common.collect.Lists;
import com.ymatou.iapi.optrade.parameter.req.ApplyRefundReq;
import com.ymatou.iapi.optrade.parameter.req.ApproveRefundBillReq;
import com.ymatou.iapi.optrade.parameter.req.PlaceOrderReq;
import com.ymatou.iapi.optrade.parameter.utill.Utils;
import com.ymatou.iapi.optrade.parameter.vo.OrderGroupVo;
import com.ymatou.iapi.optrade.parameter.vo.OrderItemVo;
import com.ymatou.iapi.optrade.parameter.vo.OrderVo;
import com.ymatou.iapi.optrade.parameter.vo.SalesRefundInfoVo;
import com.ymatou.iapi.optrade.resp.Order;
import com.ymatou.iapi.optrade.resp.TradingServiceResp;
import com.ymatou.iapi.optrade.service.PrepaidCardService;
import com.ymatou.iapi.optrade.service.RefundService;
import com.ymatou.iapi.optrade.service.SalesRefundSuccessCall;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymt.utils.tag.P3;
import com.ymttest.business.service.AccountCallServiceV2;
import com.ymttest.business.service.SQPayGateWayCallService;
import com.ymttest.business.service.TradingCallService;
import com.ymttest.database.model.AccountEntry;
import com.ymttest.database.sharding.db.sharding.model.OrderDetailPo;
import com.ymttest.database.sharding.db.sharding.model.OrderPo;
import com.ymttest.database.sharding.db.sharding.model.RefundBillPo;
import com.ymttest.database.sharding.db.sharding.model.UserRefundFundDetailPo;
import com.ymttest.database.sharding.db.sqlwapper.OrderShardingWapper;
import com.ymttest.utils.DataUtil;

@TestSuite
@Ignore
public class Ts_SalesRefundSuccess {

	private static ApproveRefundBillReq salesrefundsuccessReq;
	private static SalesRefundSuccessCall salesrefundsuccessCall;
	private static OrderShardingWapper orderShardingWapper = new OrderShardingWapper();

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("退货/退款成功完成接口");
		
		try {
			AccountCallServiceV2.resetAccount(
					AccountCallServiceV2.getAccountId(24635724),
					new BigDecimal("99999999"), new BigDecimal("99999999"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Before
	public void caseUp() {
		salesrefundsuccessReq = new ApproveRefundBillReq();
		salesrefundsuccessCall = new SalesRefundSuccessCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(salesrefundsuccessCall.getOpurl());
//		orderShardingWapper.activeDeadCommunicationsLink(orderShardingWapper);
	}

	@After
	public void caseDown() {
		Logger.end();
		orderShardingWapper.activeDeadCommunicationsLink(orderShardingWapper);
	}

	/**
	 * 平台优惠的商品下单
	 */
	public TradingServiceResp placeOrder3() {

		PlaceOrderReq placeOrderReq = TradingCallService
				.buildStandPlaceOrderReq(true);

		OrderGroupVo groupVo = placeOrderReq.getOrderGroups().get(0);

		placeOrderReq.setBizSource(null);

		long sellerId = groupVo.getSellerId();

		String sellerName = groupVo.getSellerLoginId();

		OrderVo orderVo = groupVo.getOrders().get(0);

		TradingCallService.ProductVo productVo2 = TradingCallService
				.creaderPro(sellerId, sellerName, 5);

		OrderItemVo orderItemVo2 = TradingCallService.createOrderItemVo(
				productVo2.getProductId(), productVo2.getCatalogId());

		TradingCallService.ProductVo productVo3 = TradingCallService
				.creaderPro(sellerId, sellerName, 5);

		OrderItemVo orderItemVo3 = TradingCallService.createOrderItemVo(
				productVo3.getProductId(), productVo3.getCatalogId());

		orderVo.setOrderItems(Lists.newArrayList(orderItemVo2, orderItemVo3));

		orderVo.getOrderItems().forEach(
				item -> {

					item.setYmtPromotionAmount(new BigDecimal(new Random()
							.nextInt(10)).add(BigDecimal.ONE));

					item.setProductNum(1);
				});

		TradingServiceResp placeOrderResp = TradingCallService
				.callPlaceOrderService(placeOrderReq);

		long userId = placeOrderResp.getUserId();

		long tradingId = placeOrderResp.getTradingId();

		BigDecimal useAccountAmount = placeOrderResp.getPayableAmount();

		TradingCallService.payOrder(userId, useAccountAmount, tradingId);

		return placeOrderResp;

	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_001() {
		Logger.start(true, "余额全款支付。确认收货前,订单多个商品依次全部全款退款");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(false);

			Order order = placeOrderResp.getOrderList().get(0);

			Long userId = placeOrderResp.getUserId();
			Long orderId = order.getOrderId();

			//支付
			TradingCallService.payOrder(placeOrderResp.getUserId(),
					placeOrderResp.getPayableAmount(),
					placeOrderResp.getTradingId());
			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);
			
			Thread.sleep(5000);

			List<OrderDetailPo> orderDetailPoList = order
					.getOrderDetailPoList();

			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			Map<String, Integer> beforeStockNums = new HashMap<String, Integer>();

			for (OrderDetailPo orderDetailPo : orderDetailPoList) {

				String proId = orderDetailPo.getProductId();
				String calId = orderDetailPo.getCatalogId();

				int stockNum = TradingCallService.getStockNum(proId, calId,
						false);

				beforeStockNums.put(calId, stockNum);

				Logger.comment(String.format(
						"proId：%s,calalogId:%s 下单之后的库存:%s", proId, calId,
						stockNum));
			}

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;
			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			Thread.sleep(5000);

			BigDecimal tempNoSettlementCouponAmount = BigDecimal.ZERO;

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {

				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);
					
					OrderPo orderPo = orderShardingWapper.selectOrderbyOrderId(orderId);
					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);
					BigDecimal accountAmount = orderDetailPo
							.getProductPrice().multiply(
									new BigDecimal(orderDetailPo.getProductCount())).add(orderDetailPo.getFreight());

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());

					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(1);
					expectedRefundBillPo
							.setDeductedCouponAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setThirdpartyAmount(BigDecimal.ZERO);

					BigDecimal noSettlementCouponAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						noSettlementCouponAmount = order.getOrderPo()
								.getYmtCouponAmount()
								.subtract(tempNoSettlementCouponAmount);
					}

					else {
						noSettlementCouponAmount = RefundService
								.devideThenMultiply(refund.getRefundAmount(),
										order.getOrderPayableAmount(), Utils
												.zeroIfNull(order.getOrderPo()
														.getYmtCouponAmount()));

						tempNoSettlementCouponAmount = tempNoSettlementCouponAmount
								.add(noSettlementCouponAmount);
					}

					expectedRefundBillPo.setNoSettlementCouponAmount(noSettlementCouponAmount);
					expectedRefundBillPo.setRefundBillStatus(10);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					DataUtil.verifyDecimalEquals(
							RefundService.getAccountEntry(userId, orderId + "_" + refundBillNo + "_1",
									refundBillNo).getAmount(),
							refund.getRefundAmount(), "校验取消订单退款余额入账流水金额");

				}

				for (OrderDetailPo orderDetailPo : orderDetailPoList) {

					String proId = orderDetailPo.getProductId();
					String calId = orderDetailPo.getCatalogId();

					int stockNum = TradingCallService.getStockNum(proId, calId,
							false);

					Logger.comment(String.format(
							"proId：%s,calalogId:%s 下单之后的库存:%s", proId, calId,
							stockNum));

					Logger.verifyEquals(beforeStockNums.get(calId)
							+ orderDetailPo.getProductCount(), stockNum,
							"校验退款完成会后商品库存返还");
				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_002() {
		Logger.start(true, "全部第三方支付宝支付。确认收货前,订单多个商品依次全部全款退款");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(false);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = BigDecimal.ZERO;

			//支付
			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), BigDecimal.ZERO,
					placeOrderResp.getTradingId(), "13");

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(5000);

			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);
			
			
			//发货
			TradingCallService.delivery(order.getSellerId(), orderId, false);
			//确认收货
			TradingCallService.confirmReceive(userId, orderId);
			
			Thread.sleep(5000);

			//申请退款
			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;

			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {

				Thread.sleep(4000);

				//支付网关退款回调
				SQPayGateWayCallService.refundNotifyCall("13",
						thirdTradingId.toString(), userId.intValue());

				Thread.sleep(3000);

				BigDecimal tempNoSettlementCouponAmount = BigDecimal.ZERO;
				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();
					
					OrderPo orderPo = orderShardingWapper.selectOrderbyOrderId(orderId);
					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);
					BigDecimal thirdpartyAmount = orderDetailPo
							.getProductPrice().multiply(
									new BigDecimal(orderDetailPo.getProductCount())).add(orderDetailPo.getFreight());
					
					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setCardAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());

					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(true);
					expectedRefundBillPo.setRefundStatus(1);
					expectedRefundBillPo
							.setDeductedCouponAmount(BigDecimal.ZERO);

					BigDecimal noSettlementCouponAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						noSettlementCouponAmount = order.getOrderPo()
								.getYmtCouponAmount()
								.subtract(tempNoSettlementCouponAmount);
					}

					else {
						noSettlementCouponAmount = RefundService
								.devideThenMultiply(refund.getRefundAmount(),
										order.getOrderPayableAmount(), Utils
												.zeroIfNull(order.getOrderPo()
														.getYmtCouponAmount()));

						tempNoSettlementCouponAmount = tempNoSettlementCouponAmount
								.add(noSettlementCouponAmount);
					}

					expectedRefundBillPo
							.setNoSettlementCouponAmount(noSettlementCouponAmount);
					expectedRefundBillPo.setRefundBillStatus(10);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					//用户退款资金详情表（user_refund_fund_detail）
					UserRefundFundDetailPo userRefundFundDetailPo = orderShardingWapper
							.selectUserRefundFundDetailByBizno(refundBillNo);

					UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

					expectUserRefundFundDetailPo.setPaymentId(Long
							.valueOf(thirdTradingId));
					expectUserRefundFundDetailPo.setAccountRefundStatus(-1);
					expectUserRefundFundDetailPo.setBizType(1);

					expectUserRefundFundDetailPo.setThirdpartyAmount(refund
							.getRefundAmount());
					expectUserRefundFundDetailPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
					expectUserRefundFundDetailPo.setRetryTimes(0);
					expectUserRefundFundDetailPo.setMemo("0");
					expectUserRefundFundDetailPo
							.setAccountAmount(useAccountAmount);

					RefundService.verifyUserRefundFundDetailDb(
							expectUserRefundFundDetailPo,
							userRefundFundDetailPo);
				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_003() {
		Logger.start(true, "余额+第三方支付宝组合支付。确认收货前,订单多个商品依次全部全款退款");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(false);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(270);

			String paytype = "13";

			//支付
			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), useAccountAmount,
					placeOrderResp.getTradingId(), paytype);

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall(paytype,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(5000);

			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);

			//申请退款
			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;

			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {

				Thread.sleep(4000);

				//支付网关退款回调
				SQPayGateWayCallService.refundNotifyCall("13",
						thirdTradingId.toString(), userId.intValue());

				Thread.sleep(3000);

				BigDecimal tempNoSettlementCouponAmount = BigDecimal.ZERO;

				//订单表(order)
				OrderPo orderPo = orderShardingWapper
						.selectOrderbyOrderId(orderId);

				BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
				BigDecimal refundedAccountAmount = BigDecimal.ZERO;

				BigDecimal accountAmount = BigDecimal.ZERO;
				BigDecimal thirdpartyAmount = BigDecimal.ZERO;

				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);

					String refundBillNo = refund.getRefundBillNo();
					
					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);
					BigDecimal totalAmount = refund.getRefundAmount();
					
					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							refund.getRefundAmount())) {

						accountAmount = refund.getRefundAmount();
						refundedAccountAmount = refundedAccountAmount.add(accountAmount);

					} else {

						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
						refundedAccountAmount = refundedAccountAmount.add(accountAmount);
						
						thirdpartyAmount = totalAmount.subtract(accountAmount);
					}
					
					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(1);
					expectedRefundBillPo
							.setDeductedCouponAmount(BigDecimal.ZERO);

					BigDecimal noSettlementCouponAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						noSettlementCouponAmount = order.getOrderPo()
								.getYmtCouponAmount()
								.subtract(tempNoSettlementCouponAmount);
					}

					else {
						noSettlementCouponAmount = RefundService
								.devideThenMultiply(refund.getRefundAmount(),
										order.getOrderPayableAmount(), Utils
												.zeroIfNull(order.getOrderPo()
														.getYmtCouponAmount()));

						tempNoSettlementCouponAmount = tempNoSettlementCouponAmount
								.add(noSettlementCouponAmount);
					}

					expectedRefundBillPo
							.setNoSettlementCouponAmount(noSettlementCouponAmount);

					expectedRefundBillPo.setRefundBillStatus(10);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					//用户退款资金详情表（user_refund_fund_detail）
					UserRefundFundDetailPo userRefundFundDetailPo = orderShardingWapper
							.selectUserRefundFundDetailByBizno(refundBillNo);
					
					UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

					expectUserRefundFundDetailPo.setPaymentId(Long
							.valueOf(thirdTradingId));
					expectUserRefundFundDetailPo.setBizType(1);
					expectUserRefundFundDetailPo
							.setAccountAmount(accountAmount);

					int accountRefundStatus = -1;

					if (Utils.isBiggerThan(
							expectUserRefundFundDetailPo.getAccountAmount(),
							BigDecimal.ZERO)) {

						accountRefundStatus = 4;

						//退余额校验余额账户退款流水记录
						AccountEntry accountEntry = RefundService
								.getAccountEntry(userId, orderId + "_" + refundBillNo + "_1",
										refundBillNo);

						DataUtil.verifyDecimalEquals(
								expectUserRefundFundDetailPo.getAccountAmount(),
								accountEntry.getAmount(), String.format(
										"退款单号 refundBillNo : %s 校验余额退款流水记录 ",
										refundBillNo));
					}

					expectUserRefundFundDetailPo
							.setAccountRefundStatus(accountRefundStatus);

					expectUserRefundFundDetailPo.setThirdpartyAmount(refund
							.getRefundAmount().subtract(accountAmount));
					int thirdpartyRefundStatus = -1;

					if (Utils.isBiggerThan(
							expectUserRefundFundDetailPo.getThirdpartyAmount(),
							BigDecimal.ZERO)) {
						thirdpartyRefundStatus = 4;

					}
					expectUserRefundFundDetailPo
							.setThirdpartyRefundStatus(thirdpartyRefundStatus);
					expectUserRefundFundDetailPo.setRetryTimes(0);
					expectUserRefundFundDetailPo.setMemo("0");
					
					expectUserRefundFundDetailPo.setOrderId(orderId);
					expectUserRefundFundDetailPo.setThirdpartyDiscount(BigDecimal.ZERO);
					
					RefundService.verifyUserRefundFundDetailDb(
							expectUserRefundFundDetailPo,
							userRefundFundDetailPo);
				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_004() {
		Logger.start(true, "全部第三方微信支付。确认收货前,订单多个商品依次全部全款退款");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(false);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = BigDecimal.ZERO;

			String payTypeString = "15";
			//支付
			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), BigDecimal.ZERO,
					placeOrderResp.getTradingId(), payTypeString);

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall(payTypeString,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(3000);

			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);

			//申请退款
			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;

			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {

				Thread.sleep(4000);

				//支付网关退款回调
				SQPayGateWayCallService.refundNotifyCall(payTypeString,
						thirdTradingId.toString(), userId.intValue());

				Thread.sleep(3000);

				BigDecimal tempNoSettlementCouponAmount = BigDecimal.ZERO;
				
				// 订单表(order)
				OrderPo orderPo = orderShardingWapper
						.selectOrderbyOrderId(orderId);
				BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
				BigDecimal refundedAccountAmount = BigDecimal.ZERO;

				BigDecimal accountAmount = BigDecimal.ZERO;
				BigDecimal thirdpartyAmount = BigDecimal.ZERO;
				
				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);

					String refundBillNo = refund.getRefundBillNo();

					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);
					BigDecimal totalAmount = refund.getRefundAmount();
					
					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							refund.getRefundAmount())) {

						accountAmount = refund.getRefundAmount();
						refundedAccountAmount = refundedAccountAmount.add(accountAmount);

					} else {

						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
						refundedAccountAmount = refundedAccountAmount.add(accountAmount);
						
						thirdpartyAmount = totalAmount.subtract(accountAmount);
					}
					
					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(1);
					expectedRefundBillPo
							.setDeductedCouponAmount(BigDecimal.ZERO);

					BigDecimal noSettlementCouponAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						noSettlementCouponAmount = order.getOrderPo()
								.getYmtCouponAmount()
								.subtract(tempNoSettlementCouponAmount);
					}

					else {
						noSettlementCouponAmount = RefundService
								.devideThenMultiply(refund.getRefundAmount(),
										order.getOrderPayableAmount(), Utils
												.zeroIfNull(order.getOrderPo()
														.getYmtCouponAmount()));

						tempNoSettlementCouponAmount = tempNoSettlementCouponAmount
								.add(noSettlementCouponAmount);
					}

					expectedRefundBillPo
							.setNoSettlementCouponAmount(noSettlementCouponAmount);

					expectedRefundBillPo.setRefundBillStatus(10);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					//用户退款资金详情表（user_refund_fund_detail）
					UserRefundFundDetailPo userRefundFundDetailPo = orderShardingWapper
							.selectUserRefundFundDetailByBizno(refundBillNo);

					UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

					expectUserRefundFundDetailPo.setPaymentId(Long
							.valueOf(thirdTradingId));
					expectUserRefundFundDetailPo.setAccountRefundStatus(-1);
					expectUserRefundFundDetailPo.setBizType(1);

					expectUserRefundFundDetailPo.setThirdpartyAmount(refund
							.getRefundAmount());
					expectUserRefundFundDetailPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
					expectUserRefundFundDetailPo.setRetryTimes(0);
					expectUserRefundFundDetailPo.setMemo("0");
					expectUserRefundFundDetailPo
							.setAccountAmount(useAccountAmount);

					RefundService.verifyUserRefundFundDetailDb(
							expectUserRefundFundDetailPo,
							userRefundFundDetailPo);

				}

			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_005() {
		Logger.start(true, "余额+第三方招行混合支付。确认收货前,订单多个商品依次全部全款退款");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(false);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(70);

			String paytype = "50";

			//支付
			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), useAccountAmount,
					placeOrderResp.getTradingId(), paytype);

			BigDecimal discountAmount = BigDecimal.ZERO;

			// 支付网关支付回调交易
			SQPayGateWayCallService.cmbNotifyCall(String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue(), discountAmount.toString());

			Thread.sleep(8000);

			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);

			//申请退款
			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;

			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {

				Thread.sleep(4000);

				//支付网关退款回调
				SQPayGateWayCallService.refundNotifyCall("13",
						thirdTradingId.toString(), userId.intValue());

				Thread.sleep(4000);

				BigDecimal tempNoSettlementCouponAmount = BigDecimal.ZERO;

				BigDecimal tempdisAmount = BigDecimal.ZERO;

				// 订单表(order)
				OrderPo orderPo = orderShardingWapper
						.selectOrderbyOrderId(orderId);
				BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
				BigDecimal refundedAccountAmount = BigDecimal.ZERO;

				BigDecimal accountAmount = BigDecimal.ZERO;
				BigDecimal thirdpartyAmount = BigDecimal.ZERO;

				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);
					String refundBillNo = refund.getRefundBillNo();
					
					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);
					BigDecimal totalAmount = refund.getRefundAmount();

					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							refund.getRefundAmount())) {

						accountAmount = refund.getRefundAmount();
						refundedAccountAmount = refundedAccountAmount.add(accountAmount);

					} else {

						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
						refundedAccountAmount = refundedAccountAmount.add(accountAmount);
						
						thirdpartyAmount = totalAmount.subtract(accountAmount);
					}
					
					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(1);
					expectedRefundBillPo
							.setDeductedCouponAmount(BigDecimal.ZERO);

					BigDecimal noSettlementCouponAmount = BigDecimal.ZERO;
					BigDecimal disAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						noSettlementCouponAmount = order.getOrderPo()
								.getYmtCouponAmount()
								.subtract(tempNoSettlementCouponAmount);

						disAmount = orderPo.getThirdpartyDiscount().subtract(
								tempdisAmount);
					}

					else {
						noSettlementCouponAmount = RefundService
								.devideThenMultiply(
										refund.getRefundAmount(),
										orderPo.getAccountPaidAmount()
												.add(orderPo
														.getThirdpartyPaidAmount()),
										Utils.zeroIfNull(order.getOrderPo()
												.getYmtCouponAmount()));

						disAmount = RefundService.devideThenMultiply(refund
								.getRefundAmount().subtract(accountAmount),
								orderPo.getThirdpartyPaidAmount(), orderPo
										.getThirdpartyDiscount());

						tempNoSettlementCouponAmount = tempNoSettlementCouponAmount
								.add(noSettlementCouponAmount);

						tempdisAmount = tempdisAmount.add(disAmount);
					}

					expectedRefundBillPo.setThirdpartyDiscount(disAmount);

					expectedRefundBillPo
							.setNoSettlementCouponAmount(noSettlementCouponAmount);

					expectedRefundBillPo.setRefundBillStatus(10);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					//用户退款资金详情表（user_refund_fund_detail）
					UserRefundFundDetailPo userRefundFundDetailPo = orderShardingWapper
							.selectUserRefundFundDetailByBizno(refundBillNo);

					UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

					expectUserRefundFundDetailPo.setPaymentId(Long
							.valueOf(thirdTradingId));

					expectUserRefundFundDetailPo.setBizType(1);

					expectUserRefundFundDetailPo
							.setAccountAmount(accountAmount);

					int accountRefundStatus = -1;

					if (Utils.isBiggerThan(
							expectUserRefundFundDetailPo.getAccountAmount(),
							BigDecimal.ZERO)) {

						accountRefundStatus = 4;

						//退余额校验余额账户退款流水记录
						AccountEntry accountEntry = RefundService
								.getAccountEntry(userId, orderId + "_" + refundBillNo + "_1",
										refundBillNo);

						DataUtil.verifyDecimalEquals(
								expectUserRefundFundDetailPo.getAccountAmount(),
								accountEntry.getAmount(), String.format(
										"退款单号 refundBillNo : %s 校验余额退款流水记录 ",
										refundBillNo));

					}

					expectUserRefundFundDetailPo
							.setAccountRefundStatus(accountRefundStatus);
					expectUserRefundFundDetailPo.setOrderId(orderId);

					expectUserRefundFundDetailPo.setThirdpartyAmount(refund
							.getRefundAmount().subtract(accountAmount));

					expectUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
					expectUserRefundFundDetailPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectUserRefundFundDetailPo.setRetryTimes(0);
					expectUserRefundFundDetailPo.setMemo("0");

					RefundService.verifyUserRefundFundDetailDb(
							expectUserRefundFundDetailPo,
							userRefundFundDetailPo);

				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_006() {
		Logger.start(true, "全部第三方招行支付。确认收货前,订单多个商品依次全部全款退款");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(false);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = BigDecimal.ZERO;

			String paytype = "50";

			//支付
			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), useAccountAmount,
					placeOrderResp.getTradingId(), paytype);

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall(paytype,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(5000);

			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);

			//申请退款
			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;

			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {

				Thread.sleep(4000);

				//支付网关退款回调
				SQPayGateWayCallService.refundNotifyCall("13",
						thirdTradingId.toString(), userId.intValue());

				Thread.sleep(3000);

				BigDecimal tempNoSettlementCouponAmount = BigDecimal.ZERO;

				// 订单表(order)
				OrderPo orderPo = orderShardingWapper
						.selectOrderbyOrderId(orderId);
				BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
				BigDecimal refundedAccountAmount = BigDecimal.ZERO;

				BigDecimal accountAmount = BigDecimal.ZERO;
				BigDecimal thirdpartyAmount = BigDecimal.ZERO;

				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);

					String refundBillNo = refund.getRefundBillNo();
					
					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);
					BigDecimal totalAmount = refund.getRefundAmount();

					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							refund.getRefundAmount())) {

						accountAmount = refund.getRefundAmount();
						refundedAccountAmount = refundedAccountAmount.add(accountAmount);

					} else {

						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
						refundedAccountAmount = refundedAccountAmount.add(accountAmount);
						
						thirdpartyAmount = totalAmount.subtract(accountAmount);
					}
					
					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(1);
					expectedRefundBillPo
							.setDeductedCouponAmount(BigDecimal.ZERO);

					BigDecimal noSettlementCouponAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						noSettlementCouponAmount = order.getOrderPo()
								.getYmtCouponAmount()
								.subtract(tempNoSettlementCouponAmount);
					}

					else {
						noSettlementCouponAmount = RefundService
								.devideThenMultiply(refund.getRefundAmount(),
										order.getOrderPayableAmount(), Utils
												.zeroIfNull(order.getOrderPo()
														.getYmtCouponAmount()));

						tempNoSettlementCouponAmount = tempNoSettlementCouponAmount
								.add(noSettlementCouponAmount);
					}

					expectedRefundBillPo
							.setNoSettlementCouponAmount(noSettlementCouponAmount);

					expectedRefundBillPo.setRefundBillStatus(10);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					//用户退款资金详情表（user_refund_fund_detail）
					UserRefundFundDetailPo userRefundFundDetailPo = orderShardingWapper
							.selectUserRefundFundDetailByBizno(refundBillNo);

					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							BigDecimal.ZERO)
							&& Utils.isBiggerThanOrEqual(accountPaidAmount
									.subtract(refundedAccountAmount), refund
									.getRefundAmount())) {

						accountAmount = refund.getRefundAmount();

					} else {
						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
					}

					refundedAccountAmount = refundedAccountAmount
							.add(accountAmount);

					UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

					expectUserRefundFundDetailPo.setPaymentId(Long
							.valueOf(thirdTradingId));

					expectUserRefundFundDetailPo.setBizType(1);

					expectUserRefundFundDetailPo
							.setAccountAmount(accountAmount);

					int accountRefundStatus = -1;

					if (Utils.isBiggerThan(
							expectUserRefundFundDetailPo.getAccountAmount(),
							BigDecimal.ZERO)) {

						accountRefundStatus = 4;

						//退余额校验余额账户退款流水记录
						AccountEntry accountEntry = RefundService
								.getAccountEntry(userId, refundBillNo,
										refundBillNo);

						DataUtil.verifyDecimalEquals(
								expectUserRefundFundDetailPo.getAccountAmount(),
								accountEntry.getAmount(), String.format(
										"退款单号 refundBillNo : %s 校验余额退款流水记录 ",
										refundBillNo));

					}

					expectUserRefundFundDetailPo
							.setAccountRefundStatus(accountRefundStatus);

					expectUserRefundFundDetailPo.setThirdpartyAmount(refund
							.getRefundAmount().subtract(accountAmount));

					expectUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
					expectUserRefundFundDetailPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectUserRefundFundDetailPo.setRetryTimes(0);
					expectUserRefundFundDetailPo.setMemo("0");

					RefundService.verifyUserRefundFundDetailDb(
							expectUserRefundFundDetailPo,
							userRefundFundDetailPo);

				}

			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_007() {
		Logger.start(true, "组合支付,订单部分退款,然后确认收货");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(false);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(70);

			String paytype = "13";

			//支付
			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), useAccountAmount,
					placeOrderResp.getTradingId(), paytype);

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall(paytype,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(20000);

			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);
			//发货
			TradingCallService.delivery(order.getSellerId(), orderId, false);

			//申请退款
			ApplyRefundReq applyRefundReq = RefundService
					.buildStandApplyRefundReq(order);

			applyRefundReq.getSalesRefundInfoList().remove(1);
			applyRefundReq.getSalesRefundInfoList().remove(1);

			RefundService.applyRefundCall(applyRefundReq);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;

			salesrefundsuccessReq.setRefundBillNo(applyRefundReq
					.getSalesRefundInfoList().get(0).getRefundBillNo());
			salesrefundsuccessCall.setData(salesrefundsuccessReq);

			Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行", orderId,
					i + 1));

			salesrefundsuccessCall.callService();

			Logger.verifyEquals("ok", salesrefundsuccessCall.getReturnData(),
					"验证退货退款成功返回");

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {

				Thread.sleep(4000);

				//支付网关退款回调
				SQPayGateWayCallService.refundNotifyCall("13",
						thirdTradingId.toString(), userId.intValue());

				Thread.sleep(5000);

				TradingCallService.confirmReceive(userId, orderId);

				// 订单表(order)
				OrderPo orderPo = orderShardingWapper
						.selectOrderbyOrderId(orderId);
				BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
				BigDecimal refundedAccountAmount = BigDecimal.ZERO;

				BigDecimal accountAmount = BigDecimal.ZERO;
				BigDecimal thirdpartyAmount = BigDecimal.ZERO;

				// 数据库验证
				for (int j = 0; j < 1; j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);

					String refundBillNo = refund.getRefundBillNo();

					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);
					BigDecimal totalAmount = refund.getRefundAmount();

					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							refund.getRefundAmount())) {

						accountAmount = refund.getRefundAmount();
					} else {

						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
						thirdpartyAmount = totalAmount.subtract(accountAmount);
					}
					
					refundedAccountAmount = refundedAccountAmount.add(accountAmount);
					
					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(1);
					expectedRefundBillPo
							.setDeductedCouponAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setNoSettlementCouponAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setRefundBillStatus(10);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					//用户退款资金详情表（user_refund_fund_detail）
					UserRefundFundDetailPo userRefundFundDetailPo = orderShardingWapper
							.selectUserRefundFundDetailByBizno(refundBillNo);

					UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

					expectUserRefundFundDetailPo.setPaymentId(Long
							.valueOf(thirdTradingId));

					expectUserRefundFundDetailPo.setBizType(1);

					expectUserRefundFundDetailPo
							.setAccountAmount(accountAmount);

					int accountRefundStatus = -1;

					if (Utils.isBiggerThan(
							expectUserRefundFundDetailPo.getAccountAmount(),
							BigDecimal.ZERO)) {

						accountRefundStatus = 4;

						//退余额校验余额账户退款流水记录
						AccountEntry accountEntry = RefundService
								.getAccountEntry(userId, orderId + "_" + refundBillNo + "_1",
										refundBillNo);

						DataUtil.verifyDecimalEquals(
								expectUserRefundFundDetailPo.getAccountAmount(),
								accountEntry.getAmount(), String.format(
										"退款单号 refundBillNo : %s 校验余额退款流水记录 ",
										refundBillNo));
					}
					
					expectUserRefundFundDetailPo
							.setAccountRefundStatus(accountRefundStatus);
					expectUserRefundFundDetailPo.setThirdpartyAmount(refund
							.getRefundAmount().subtract(accountAmount));
					expectUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
					expectUserRefundFundDetailPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectUserRefundFundDetailPo.setRetryTimes(0);
					expectUserRefundFundDetailPo.setMemo("0");

					RefundService.verifyUserRefundFundDetailDb(
							expectUserRefundFundDetailPo,
							userRefundFundDetailPo);

				}

			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_008() {
		Logger.start(true, "组合支付,接单后,一个订单多个商品，货全部退完,订单状态为用户取消，剩余部分金额给商家结算");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(false);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(70);

			String paytype = "13";

			//支付
			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), useAccountAmount,
					placeOrderResp.getTradingId(), paytype);

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall(paytype,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(15000);

			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);

			//申请退款
			ApplyRefundReq applyRefundReq = RefundService
					.buildStandApplyRefundReq(order);

			// 货退完，款还有部分未退
			applyRefundReq.getSalesRefundInfoList().forEach(
					re -> re.setRefundAmount(re.getRefundAmount().subtract(
							BigDecimal.TEN)));

			RefundService.applyRefundCall(applyRefundReq);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;

			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			Thread.sleep(4000);

			//支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13",
					thirdTradingId.toString(), userId.intValue());

			Thread.sleep(3000);

			//订单表(order)
			OrderPo orderPo = orderShardingWapper.selectOrderbyOrderId(orderId);

			Logger.verifyEquals(12, orderPo.getOrderStatus(), "校验订单状态为用户取消12");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	//TODO 后续校验退款生成的结算单
	public void Tc_SalesRefundSuccess_009() {
		Logger.start(true, "余额+第三方支付宝组合支付。确认收货后,订单多个商品依次全部全款退款");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(true);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			long orderId = order.getOrderId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = BigDecimal.ZERO;

			String paytype = "13";
			//支付
			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), useAccountAmount,
					placeOrderResp.getTradingId(), paytype);

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall(paytype,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(6000);

			//接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);
			//发货
			TradingCallService.delivery(sellerId, orderId, false);
			//确认收货
			TradingCallService.confirmReceive(userId, orderId);

			//申请退款
			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;

			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {

				Thread.sleep(4000);

				//支付网关退款回调
				SQPayGateWayCallService.refundNotifyCall(paytype,
						thirdTradingId.toString(), userId.intValue());

				Thread.sleep(3000);

				// 订单表(order)
				OrderPo orderPo = orderShardingWapper
						.selectOrderbyOrderId(orderId);
				BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
				BigDecimal refundedAccountAmount = BigDecimal.ZERO;

				BigDecimal accountAmount = BigDecimal.ZERO;
				BigDecimal thirdpartyAmount = BigDecimal.ZERO;

				BigDecimal tempCouponAmount = BigDecimal.ZERO;

				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);

					String refundBillNo = refund.getRefundBillNo();

					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);
					BigDecimal totalAmount = refund.getRefundAmount();

					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							refund.getRefundAmount())) {

						accountAmount = refund.getRefundAmount();
					} else {

						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
						thirdpartyAmount = totalAmount.subtract(accountAmount);
					}
					
					refundedAccountAmount = refundedAccountAmount.add(accountAmount);
					
					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(true);
					expectedRefundBillPo.setRefundStatus(1);

					BigDecimal deductedCouponAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						deductedCouponAmount = order.getOrderPo()
								.getYmtCouponAmount()
								.subtract(tempCouponAmount);
					}

					else {
						deductedCouponAmount = RefundService
								.devideThenMultiply(refund.getRefundAmount(),
										order.getOrderPayableAmount(), Utils
												.zeroIfNull(order.getOrderPo()
														.getYmtCouponAmount()));

						tempCouponAmount = tempCouponAmount
								.add(deductedCouponAmount);
					}

					expectedRefundBillPo
							.setNoSettlementCouponAmount(BigDecimal.ZERO);
					expectedRefundBillPo
							.setDeductedCouponAmount(deductedCouponAmount);

					expectedRefundBillPo.setRefundBillStatus(10);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					//用户退款资金详情表（user_refund_fund_detail）
					UserRefundFundDetailPo userRefundFundDetailPo = orderShardingWapper
							.selectUserRefundFundDetailByBizno(refundBillNo);

					UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

					expectUserRefundFundDetailPo.setPaymentId(Long
							.valueOf(thirdTradingId));

					int accountRefundStatus = -1;

					if (Utils.isBiggerThan(accountAmount, BigDecimal.ZERO)) {

						accountRefundStatus = 4;

						//退余额校验余额账户退款流水记录
						AccountEntry accountEntry = RefundService
								.getAccountEntry(userId, refundBillNo,
										refundBillNo);

						DataUtil.verifyDecimalEquals(accountAmount,
								accountEntry.getAmount(), String.format(
										"退款单号 refundBillNo : %s 校验用户余额退款流水记录 ",
										refundBillNo));
					}

					//商家扣款流水记录
					AccountEntry sellerAccountEntry = RefundService
							.getAccountEntry(sellerId, orderId + "_" + refundBillNo + "_1",
									refundBillNo);

					DataUtil.verifyDecimalEquals(
							refund.getRefundAmount()
									.add(expectedRefundBillPo
											.getDeductedCouponAmount())
									.divide(new BigDecimal(-1)),
							sellerAccountEntry.getAmount(),
							String.format(
									"退款单号 refundBillNo : %s 校验商家 sellerId : %s 账户退款 扣款 流水记录 ",
									refundBillNo, sellerId));

					expectUserRefundFundDetailPo
							.setAccountAmount(accountAmount);
					expectUserRefundFundDetailPo
							.setAccountRefundStatus(accountRefundStatus);
					expectUserRefundFundDetailPo.setBizType(1);
					expectUserRefundFundDetailPo.setThirdpartyAmount(refund
							.getRefundAmount().subtract(accountAmount));
					expectUserRefundFundDetailPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
					expectUserRefundFundDetailPo.setRetryTimes(0);
					expectUserRefundFundDetailPo.setMemo("0");

					RefundService.verifyUserRefundFundDetailDb(
							expectUserRefundFundDetailPo,
							userRefundFundDetailPo);
				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_010() {
		Logger.start(true, "全部第三方支付宝支付。确认收货后,订单多个商品依次全部全款退款");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(true);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			long orderId = order.getOrderId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = BigDecimal.ZERO;

			String paytype = "13";
			//支付
			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), useAccountAmount,
					placeOrderResp.getTradingId(), paytype);

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall(paytype,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(5000);

			//接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);
			//发货
			TradingCallService.delivery(sellerId, orderId, false);
			//确认收货
			TradingCallService.confirmReceive(userId, orderId);

			//申请退款
			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;

			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {

				Thread.sleep(4000);

				//支付网关退款回调
				SQPayGateWayCallService.refundNotifyCall(paytype,
						thirdTradingId.toString(), userId.intValue());

				Thread.sleep(3000);

				// 订单表(order)
				OrderPo orderPo = orderShardingWapper
						.selectOrderbyOrderId(orderId);
				BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
				BigDecimal refundedAccountAmount = BigDecimal.ZERO;

				BigDecimal accountAmount = BigDecimal.ZERO;
				BigDecimal thirdpartyAmount = BigDecimal.ZERO;

				BigDecimal tempCouponAmount = BigDecimal.ZERO;

				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);

					String refundBillNo = refund.getRefundBillNo();

					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);
					BigDecimal totalAmount = refund.getRefundAmount();

					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							refund.getRefundAmount())) {

						accountAmount = refund.getRefundAmount();
					} else {

						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
						thirdpartyAmount = totalAmount.subtract(accountAmount);
					}
					
					refundedAccountAmount = refundedAccountAmount.add(accountAmount);
					
					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(true);
					expectedRefundBillPo.setRefundStatus(1);

					BigDecimal deductedCouponAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						deductedCouponAmount = order.getOrderPo()
								.getYmtCouponAmount()
								.subtract(tempCouponAmount);
					}

					else {
						deductedCouponAmount = RefundService
								.devideThenMultiply(refund.getRefundAmount(),
										order.getOrderPayableAmount(), Utils
												.zeroIfNull(order.getOrderPo()
														.getYmtCouponAmount()));

						tempCouponAmount = tempCouponAmount
								.add(deductedCouponAmount);
					}

					expectedRefundBillPo
							.setNoSettlementCouponAmount(BigDecimal.ZERO);
					expectedRefundBillPo
							.setDeductedCouponAmount(deductedCouponAmount);

					expectedRefundBillPo.setRefundBillStatus(10);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					//用户退款资金详情表（user_refund_fund_detail）
					UserRefundFundDetailPo userRefundFundDetailPo = orderShardingWapper
							.selectUserRefundFundDetailByBizno(refundBillNo);

					UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

					expectUserRefundFundDetailPo.setPaymentId(Long
							.valueOf(thirdTradingId));

					int accountRefundStatus = -1;

					if (Utils.isBiggerThan(accountAmount, BigDecimal.ZERO)) {

						accountRefundStatus = 4;

						//退余额校验余额账户退款流水记录
						AccountEntry accountEntry = RefundService
								.getAccountEntry(userId, refundBillNo,
										refundBillNo);

						DataUtil.verifyDecimalEquals(accountAmount,
								accountEntry.getAmount(), String.format(
										"退款单号 refundBillNo : %s 校验余额退款流水记录 ",
										refundBillNo));
					}
					//商家扣款流水记录
					AccountEntry sellerAccountEntry = RefundService
							.getAccountEntry(sellerId, orderId + "_" + refundBillNo + "_1",
									refundBillNo);

					DataUtil.verifyDecimalEquals(
							refund.getRefundAmount()
									.add(expectedRefundBillPo
											.getDeductedCouponAmount())
									.divide(new BigDecimal(-1)),
							sellerAccountEntry.getAmount(),
							String.format(
									"退款单号 refundBillNo : %s 校验商家 sellerId : %s 账户退款 扣款 流水记录 ",
									refundBillNo, sellerId));

					expectUserRefundFundDetailPo
							.setAccountAmount(accountAmount);
					expectUserRefundFundDetailPo
							.setAccountRefundStatus(accountRefundStatus);
					expectUserRefundFundDetailPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectUserRefundFundDetailPo.setThirdpartyAmount(refund
							.getRefundAmount().subtract(accountAmount));
					expectUserRefundFundDetailPo.setBizType(1);
					expectUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
					expectUserRefundFundDetailPo.setRetryTimes(0);
					expectUserRefundFundDetailPo.setMemo("0");

					RefundService.verifyUserRefundFundDetailDb(
							expectUserRefundFundDetailPo,
							userRefundFundDetailPo);

				}

			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@SuppressWarnings("static-access")
	@Test
	@Category({P1.class})
	@TestCase
	@Ignore
	public void Tc_SalesRefundSuccess_011() {
		Logger.start(true, "确认收货后,商家备用金不够,退货退款结算失败");
		try {

			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(false);

			Order order = placeOrderResp.getOrderList().get(0);
			long orderId = order.getOrderId();
			Long sellerId = order.getSellerId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = BigDecimal.ZERO;

			//支付
			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), BigDecimal.ZERO,
					placeOrderResp.getTradingId(), "13");

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(5000);

			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);
			//发货
			TradingCallService.delivery(sellerId, orderId, false);
			//确认收货
			TradingCallService.confirmReceive(userId, orderId);

			// 申请退款
			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			BigDecimal refundAmount = applyRefundReq.getSalesRefundInfoList()
					.get(0).getRefundAmount();

			String refundBillNo = applyRefundReq.getSalesRefundInfoList()
					.get(0).getRefundBillNo();

			// 重置商家余额			
			AccountCallServiceV2.resetAccount(
					AccountCallServiceV2.getAccountId(sellerId.intValue()),
					refundAmount.subtract(BigDecimal.ONE), BigDecimal.ZERO);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);
			salesrefundsuccessReq.setRefundBillNo(refundBillNo);
			salesrefundsuccessCall.setData(salesrefundsuccessReq);
			salesrefundsuccessCall.callService();
			Logger.verifyEquals("ok", salesrefundsuccessCall.getReturnData(),
					"验证退货退款成功返回");

			Thread.sleep(3000);

			SalesRefundInfoVo refund = applyRefundReq.getSalesRefundInfoList()
					.get(0);
			OrderPo orderPo = orderShardingWapper.selectOrderbyOrderId(orderId);
			OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(0);
			BigDecimal thirdPartyAmount = orderDetailPo
					.getProductPrice().multiply(
							new BigDecimal(orderDetailPo.getProductCount())).add(orderDetailPo.getFreight());
			
			refundBillNo = refund.getRefundBillNo();

			RefundBillPo expectedRefundBillPo = new RefundBillPo();

			expectedRefundBillPo.setOrderId(orderDetailPo.getOrderId());
			expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
			expectedRefundBillPo.setSellerId(orderPo.getSellerId());
			expectedRefundBillPo.setUserId(orderPo.getUserId());
			expectedRefundBillPo.setThirdpartyDiscount(orderDetailPo.getThirdpartyDiscount());
			expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
			expectedRefundBillPo.setDeductedCouponAmount(BigDecimal.ZERO);
			expectedRefundBillPo.setNoSettlementCouponAmount(BigDecimal.ZERO);
			expectedRefundBillPo.setAccountAmount(BigDecimal.ZERO);
			expectedRefundBillPo.setCardAmount(BigDecimal.ZERO);
			expectedRefundBillPo.setThirdpartyAmount(thirdPartyAmount);
			
			expectedRefundBillPo.setRefundBillNo(refundBillNo);
			expectedRefundBillPo.setCatalogId(refund.getCatalogId());
			expectedRefundBillPo.setTotalAmount(refund.getRefundAmount());

			expectedRefundBillPo.setTopspeedRefund(false);
			expectedRefundBillPo.setAfterReceiving(true);
			expectedRefundBillPo.setRefundStatus(0);

			expectedRefundBillPo.setRefundBillStatus(10);

			RefundBillPo actualRefundBillPo = orderShardingWapper
					.selectRefundBillByBillNo(refundBillNo);

			RefundService.verifyRefundBillDb(expectedRefundBillPo,
					actualRefundBillPo);

			UserRefundFundDetailPo userRefundFundDetailPo = orderShardingWapper
					.selectUserRefundFundDetailByBizno(refundBillNo);

			UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

			expectUserRefundFundDetailPo.setBizType(1);
			expectUserRefundFundDetailPo.setMemo("0");
			expectUserRefundFundDetailPo.setAccountAmount(BigDecimal.ZERO);
			expectUserRefundFundDetailPo.setThirdpartyDiscount(BigDecimal.ZERO);
			expectUserRefundFundDetailPo.setThirdpartyAmount(thirdPartyAmount);
			expectUserRefundFundDetailPo.setOrderId(orderId);
			expectUserRefundFundDetailPo.setPaymentId(thirdTradingId);
			expectUserRefundFundDetailPo.setAccountRefundStatus(-1);
			expectUserRefundFundDetailPo.setThirdpartyRefundStatus(1);

			expectUserRefundFundDetailPo.setRetryTimes(0);
			
			//expectUserRefundFundDetailPo.setMemo("9002:可用余额不足");

			RefundService.verifyUserRefundFundDetailDb(
					expectUserRefundFundDetailPo, userRefundFundDetailPo);

			// 重置商家余额			
			AccountCallServiceV2.resetAccount(
					AccountCallServiceV2.getAccountId(sellerId.intValue()),
					new BigDecimal(9999999), BigDecimal.ZERO);

			//退款补偿
			RefundService.retryRefund();

			//退款补偿
			RefundService.retryRefund();

			Logger.comment("退款补偿");

			Thread.sleep(3000);

			orderShardingWapper.shardingSqlSession.clearCache();

			userRefundFundDetailPo = orderShardingWapper
					.selectUserRefundFundDetailByBizno(refundBillNo);
			
			expectUserRefundFundDetailPo.setAccountRefundStatus(-1);
			expectUserRefundFundDetailPo.setThirdpartyRefundStatus(3);
			expectUserRefundFundDetailPo.setRetryTimes(1);
			//expectUserRefundFundDetailPo.setMemo("0");

			RefundService.verifyUserRefundFundDetailDb(
					expectUserRefundFundDetailPo, userRefundFundDetailPo);

			actualRefundBillPo = orderShardingWapper
					.selectRefundBillByBillNo(refundBillNo);

			expectedRefundBillPo.setRefundStatus(0);

			RefundService.verifyRefundBillDb(expectedRefundBillPo,
					actualRefundBillPo);

			/*	//退余额校验余额账户退款流水记录
				AccountEntry accountEntry = RefundService.getAccountEntry(userId,
						refundBillNo, refundBillNo);

				DataUtil.verifyDecimalEquals(refund.getRefundAmount(), accountEntry
						.getAmount(), String.format(
						"退款单号 refundBillNo : %s 校验余额退款流水记录 ", refundBillNo));*/

			//商家扣款流水记录
			AccountEntry sellerAccountEntry = RefundService.getAccountEntry(
					sellerId, orderId + "_" + refundBillNo + "_1", refundBillNo);

			DataUtil.verifyDecimalEquals(
					refund.getRefundAmount()
							.add(Utils.zeroIfNull(expectedRefundBillPo
									.getDeductedCouponAmount()))
							.divide(new BigDecimal(-1)),
					sellerAccountEntry.getAmount(),
					String.format(
							"退款单号 refundBillNo : %s 校验商家 sellerId : %s 账户退款 扣款 流水记录 ",
							refundBillNo, sellerId));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_012() {
		Logger.start(true, "下单使用分别使用平台券优惠券，商家优惠券，多个商品依次全部退款，"
				+ "校验平台券金额按比例退，商家优惠券金额不退");
		try {

			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(true);

			Order order = placeOrderResp.getOrderList().get(0);

			Long orderId = order.getOrderId();

			//支付
			TradingCallService.payOrder(placeOrderResp.getUserId(),
					placeOrderResp.getPayableAmount(),
					placeOrderResp.getTradingId());
			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);

			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;
			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			Thread.sleep(5000);

			BigDecimal tempNoSettlementCouponAmount = BigDecimal.ZERO;

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {
				
				// 订单表(order)
				OrderPo orderPo = orderShardingWapper
						.selectOrderbyOrderId(orderId);
				BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
				BigDecimal refundedAccountAmount = BigDecimal.ZERO;

				BigDecimal accountAmount = BigDecimal.ZERO;
				BigDecimal thirdpartyAmount = BigDecimal.ZERO;
				
				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);

					String refundBillNo = refund.getRefundBillNo();

					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);
					BigDecimal totalAmount = refund.getRefundAmount();

					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							refund.getRefundAmount())) {

						accountAmount = refund.getRefundAmount();
					} else {

						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
						thirdpartyAmount = totalAmount.subtract(accountAmount);
					}
					
					refundedAccountAmount = refundedAccountAmount.add(accountAmount);
					
					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(orderPo.getUserId());
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(1);
					expectedRefundBillPo
							.setDeductedCouponAmount(BigDecimal.ZERO);

					BigDecimal noSettlementCouponAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						noSettlementCouponAmount = order.getOrderPo()
								.getYmtCouponAmount()
								.subtract(tempNoSettlementCouponAmount);
					}

					else {
						noSettlementCouponAmount = RefundService
								.devideThenMultiply(refund.getRefundAmount(),
										order.getOrderPayableAmount(), Utils
												.zeroIfNull(order.getOrderPo()
														.getYmtCouponAmount()));

						tempNoSettlementCouponAmount = tempNoSettlementCouponAmount
								.add(noSettlementCouponAmount);
					}

					expectedRefundBillPo
							.setNoSettlementCouponAmount(noSettlementCouponAmount);

					expectedRefundBillPo.setRefundBillStatus(10);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);
				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P3.class})
	@TestCase
	public void Tc_SalesRefundSuccess_013() {
		Logger.start(true, "一个订单一个商品,订单已发货，货全部取消,还有金额没退的。订单状态不变");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(true);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(70);

			String paytype = "13";

			//支付
			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), useAccountAmount,
					placeOrderResp.getTradingId(), paytype);

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall(paytype,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(5000);

			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);
			//发货
			TradingCallService.delivery(order.getSellerId(), orderId, false);

			//申请退款
			ApplyRefundReq applyRefundReq = RefundService
					.buildStandApplyRefundReq(order);

			// 货退完，款还有部分未退
			applyRefundReq.getSalesRefundInfoList().forEach(
					re -> re.setRefundAmount(re.getRefundAmount().subtract(
							BigDecimal.TEN)));

			RefundService.applyRefundCall(applyRefundReq);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;

			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			Thread.sleep(4000);

			//支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13",
					thirdTradingId.toString(), userId.intValue());

			Thread.sleep(3000);

			//订单表(order)
			OrderPo orderPo = orderShardingWapper.selectOrderbyOrderId(orderId);

			Logger.verifyEquals(3, orderPo.getOrderStatus(), "校验订单状态不变");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_014() {
		Logger.start(true, "余额全款支付。确认收货前,订单极速退款");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(true);

			Order order = placeOrderResp.getOrderList().get(0);

			Long userId = placeOrderResp.getUserId();
			Long orderId = order.getOrderId();

			//支付
			TradingCallService.payOrder(placeOrderResp.getUserId(),
					placeOrderResp.getPayableAmount(),
					placeOrderResp.getTradingId());
			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);

			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);
			salesrefundsuccessReq.setTopspeedRefund(true);

			int i = 0;
			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			Thread.sleep(5000);

			BigDecimal tempNoSettlementCouponAmount = BigDecimal.ZERO;

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {
				
				// 订单表(order)
				OrderPo orderPo = orderShardingWapper
						.selectOrderbyOrderId(orderId);
				BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
				BigDecimal refundedAccountAmount = BigDecimal.ZERO;

				BigDecimal accountAmount = BigDecimal.ZERO;
				BigDecimal thirdpartyAmount = BigDecimal.ZERO;
				
				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);

					String refundBillNo = refund.getRefundBillNo();

					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);
					BigDecimal totalAmount = refund.getRefundAmount();

					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							refund.getRefundAmount())) {

						accountAmount = refund.getRefundAmount();
					} else {

						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
						thirdpartyAmount = totalAmount.subtract(accountAmount);
					}
					
					refundedAccountAmount = refundedAccountAmount.add(accountAmount);
					
					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(orderPo.getUserId());
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());

					expectedRefundBillPo.setTopspeedRefund(true);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(1);
					expectedRefundBillPo
							.setDeductedCouponAmount(BigDecimal.ZERO);

					BigDecimal noSettlementCouponAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						noSettlementCouponAmount = order.getOrderPo()
								.getYmtCouponAmount()
								.subtract(tempNoSettlementCouponAmount);
					}

					else {
						noSettlementCouponAmount = RefundService
								.devideThenMultiply(refund.getRefundAmount(),
										order.getOrderPayableAmount(), Utils
												.zeroIfNull(order.getOrderPo()
														.getYmtCouponAmount()));

						tempNoSettlementCouponAmount = tempNoSettlementCouponAmount
								.add(noSettlementCouponAmount);
					}
					
					expectedRefundBillPo.setNoSettlementCouponAmount(noSettlementCouponAmount);
					expectedRefundBillPo.setRefundBillStatus(10);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					DataUtil.verifyDecimalEquals(
							RefundService.getAccountEntry(userId, orderId + "_" + refundBillNo + "_1",
									refundBillNo).getAmount(),
							refund.getRefundAmount(), "校验取消订单退款余额入账流水金额");
				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_015() {
		Logger.start(true, "退款退货,校验库存返还情况");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.placeOrder3(true);

			Order order = placeOrderResp.getOrderList().get(0);

			Long orderId = order.getOrderId();

			//支付
			TradingCallService.payOrder(placeOrderResp.getUserId(),
					placeOrderResp.getPayableAmount(),
					placeOrderResp.getTradingId());
			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);

			List<OrderDetailPo> orderDetailPoList = order
					.getOrderDetailPoList();

			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			Map<String, Integer> beforeStockNums = new HashMap<String, Integer>();

			for (OrderDetailPo orderDetailPo : orderDetailPoList) {

				String proId = orderDetailPo.getProductId();
				String calId = orderDetailPo.getCatalogId();

				int stockNum = TradingCallService.getStockNum(proId, calId,
						false);

				beforeStockNums.put(calId, stockNum);

				Logger.comment(String.format(
						"proId：%s,calalogId:%s 下单之后的库存:%s", proId, calId,
						stockNum));
			}

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;
			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			Thread.sleep(5000);

			for (OrderDetailPo orderDetailPo : orderDetailPoList) {

				String proId = orderDetailPo.getProductId();
				String calId = orderDetailPo.getCatalogId();

				int stockNum = TradingCallService.getStockNum(proId, calId,
						false);

				Logger.comment(String.format(
						"proId：%s,calalogId:%s 下单之后的库存:%s", proId, calId,
						stockNum));

				Logger.verifyEquals(
						beforeStockNums.get(calId)
								+ orderDetailPo.getProductCount(), stockNum,
						"校验退款完成会后商品库存返还");
			}

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_027() {
		Logger.start(true, "使用了预付卡订单，全余额支付。确认收货前,订单多个商品依次全部全款退款");
		try {
			TradingServiceResp placeOrderResp = PrepaidCardService
					.placeOrder2(false);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			// 用余额支付金额
			BigDecimal useAccountAmount = totalPrice;

			// 支付订单 余额+支付宝组合支付
			// 13 为 app国际支付宝，15 微信
			String payType = "13";

			TradingCallService.payOrder(userId, useAccountAmount, tradingId,
					payType);

			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			// 申请退款
			ApplyRefundReq refundReq = RefundService.applyRefund(order);

			BigDecimal totalRefundAmount = refundReq.getSalesRefundInfoList()
					.stream().map(SalesRefundInfoVo::getRefundAmount)
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			salesrefundsuccessReq.setOrderId(orderId);

			for (int i = 0; i < refundReq.getSalesRefundInfoList().size(); i++) {

				SalesRefundInfoVo salesRefundInfoVo = refundReq
						.getSalesRefundInfoList().get(i);

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());

				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("退该订单号 %s 第%s件商品", orderId, i + 1));
				salesrefundsuccessCall.callService();

			}

			Logger.verifyEquals("ok", salesrefundsuccessCall.getReturnData(),
					"验证退货退款成功返回");

			// 订单表(order)
			OrderPo ymtOrders = orderShardingWapper
					.selectOrderbyOrderId(orderId);

			BigDecimal totalCard = BigDecimal.ZERO;

			for (SalesRefundInfoVo refundInfoVo : refundReq
					.getSalesRefundInfoList()) {

				totalCard = PrepaidCardService.getCardEntry(userId.intValue(),
						refundInfoVo.getRefundBillNo()).add(totalCard);
			}

			DataUtil.verifyDecimalEquals(ymtOrders.getCardAmount(), totalCard,
					"校验取消订单退回的预付卡金额");

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(
					totalRefundAmount.subtract(ymtOrders.getCardAmount()),
					afterAmount.subtract(beforeAmount), "校验取消订单退回的资金账户金额");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_028() {
		Logger.start(true, "使用了预付卡订单，余额+第三方支付宝组合支付。确认收货前,订单多个商品依次全部全款退款");
		try {

			TradingServiceResp placeOrderResp = PrepaidCardService
					.placeOrder2(true);

			Order order = placeOrderResp.getOrderList().get(0);
			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			// 用余额支付金额
			BigDecimal useAccountAmount = new BigDecimal(47);
			// 支付订单 余额+支付宝组合支付
			// 13 为 app国际支付宝，15 微信
			String payType = "13";

			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), useAccountAmount,
					placeOrderResp.getTradingId(), payType);

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall(payType,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			// 等待支付网关异步处理
			Thread.sleep(5000);
			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);
			// 申请退款
			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			salesrefundsuccessReq.setOrderId(orderId);

			for (int i = 0; i < applyRefundReq.getSalesRefundInfoList().size(); i++) {

				SalesRefundInfoVo salesRefundInfoBean = applyRefundReq
						.getSalesRefundInfoList().get(i);

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoBean
						.getRefundBillNo());

				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("退该订单号 %s 第%s件商品", orderId, i + 1));
				salesrefundsuccessCall.callService();
			}

			Logger.verifyEquals("ok", salesrefundsuccessCall.getReturnData(),
					"验证退货退款成功返回");

			Thread.sleep(4000);
			BigDecimal tempNoSettlementCouponAmount = BigDecimal.ZERO;
			//支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13",
					thirdTradingId.toString(), userId.intValue());

			Thread.sleep(3000);

			// 订单表(order)
			OrderPo orderPo = orderShardingWapper
					.selectOrderbyOrderId(orderId);
			BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
			BigDecimal cardPaidAmount = orderPo.getCardAmount();
			BigDecimal refundedAccountAmount = BigDecimal.ZERO;

			BigDecimal accountAmount = BigDecimal.ZERO;
			BigDecimal thirdpartyAmount = BigDecimal.ZERO;
			BigDecimal cardAmount = BigDecimal.ZERO;

			//已退款的预付卡金额
			BigDecimal refundedCardAmount = BigDecimal.ZERO;

			// 数据库验证
			for (int j = 0; j < applyRefundReq.getSalesRefundInfoList().size(); j++) {

				SalesRefundInfoVo refund = applyRefundReq
						.getSalesRefundInfoList().get(j);

				String refundBillNo = refund.getRefundBillNo();
				RefundBillPo actualRefundBillPo = orderShardingWapper
						.selectRefundBillByBillNo(refundBillNo);
				
				OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);

				cardAmount = actualRefundBillPo.getCardAmount();
				
				//退款，优先退 预付卡
				if (Utils.isBiggerThanOrEqual(
						cardPaidAmount.subtract(refundedCardAmount),
						refund.getRefundAmount()))
					cardAmount = refund.getRefundAmount();
				else
					cardAmount = cardPaidAmount.subtract(refundedCardAmount);
				
				refundedCardAmount = refundedCardAmount.add(cardAmount);

				//退款减去 退 预付卡
				BigDecimal refundAmount = refund.getRefundAmount().subtract(
						cardAmount);
				
				//余额支付大于退款金额，先退余额
				if (Utils.isBiggerThanOrEqual(
						accountPaidAmount.subtract(refundedAccountAmount),
						refundAmount)) {

					accountAmount = refundAmount;
				} else {

					accountAmount = accountPaidAmount
							.subtract(refundedAccountAmount);
					thirdpartyAmount = refundAmount.subtract(accountAmount);
				}
				
				refundedAccountAmount = refundedAccountAmount.add(accountAmount);
				
				RefundBillPo expectedRefundBillPo = new RefundBillPo();

				expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
				expectedRefundBillPo.setOrderId(orderId);
				expectedRefundBillPo.setSellerId(orderPo.getSellerId());
				expectedRefundBillPo.setUserId(orderPo.getUserId());
				expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
				expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
				expectedRefundBillPo.setAccountAmount(accountAmount);
				expectedRefundBillPo.setCardAmount(cardAmount);
				expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
				expectedRefundBillPo.setRefundBillNo(refundBillNo);
				expectedRefundBillPo.setCatalogId(refund.getCatalogId());
				expectedRefundBillPo.setTotalAmount(refund
						.getRefundAmount());
				expectedRefundBillPo.setTopspeedRefund(false);
				expectedRefundBillPo.setAfterReceiving(false);
				expectedRefundBillPo.setRefundStatus(1);
				expectedRefundBillPo.setDeductedCouponAmount(BigDecimal.ZERO);
				BigDecimal noSettlementCouponAmount = BigDecimal.ZERO;

				if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

					noSettlementCouponAmount = orderPo
							.getYmtCouponAmount()
							.subtract(tempNoSettlementCouponAmount);
				}

				else {
					noSettlementCouponAmount = RefundService
							.devideThenMultiply(refund.getRefundAmount(),
									order.getOrderPayableAmount().add(orderPo.getCardAmount()), Utils
											.zeroIfNull(orderPo
													.getYmtCouponAmount()));

					tempNoSettlementCouponAmount = tempNoSettlementCouponAmount
							.add(noSettlementCouponAmount);
				}

				expectedRefundBillPo
						.setNoSettlementCouponAmount(noSettlementCouponAmount);

				expectedRefundBillPo.setRefundBillStatus(10);

				RefundService.verifyRefundBillDb(expectedRefundBillPo,
						actualRefundBillPo);

				if (cardAmount.compareTo(BigDecimal.ZERO) == 1)
					continue;
				
				//用户退款资金详情表（user_refund_fund_detail）
				UserRefundFundDetailPo userRefundFundDetailPo = orderShardingWapper
						.selectUserRefundFundDetailByBizno(refundBillNo);

				UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

				expectUserRefundFundDetailPo.setPaymentId(Long
						.valueOf(thirdTradingId));

				expectUserRefundFundDetailPo.setBizType(1);

				expectUserRefundFundDetailPo.setAccountAmount(accountAmount);

				int accountRefundStatus = -1;

				if (Utils.isBiggerThan(
						expectUserRefundFundDetailPo.getAccountAmount(),
						BigDecimal.ZERO)) {

					accountRefundStatus = 4;

					//退余额校验余额账户退款流水记录
					AccountEntry accountEntry = RefundService.getAccountEntry(
							userId, refundBillNo, refundBillNo);

					DataUtil.verifyDecimalEquals(expectUserRefundFundDetailPo
							.getAccountAmount(), accountEntry.getAmount(),
							String.format("退款单号 refundBillNo : %s 校验余额退款流水记录 ",
									refundBillNo));
				}

				expectUserRefundFundDetailPo
						.setAccountRefundStatus(accountRefundStatus);

				expectUserRefundFundDetailPo.setThirdpartyAmount(refundAmount
						.subtract(accountAmount));

				int thirdpartyRefundStatus = -1;

				if (Utils.isBiggerThan(
						expectUserRefundFundDetailPo.getThirdpartyAmount(),
						BigDecimal.ZERO)) {
					thirdpartyRefundStatus = 4;

				}
				expectUserRefundFundDetailPo
						.setThirdpartyRefundStatus(thirdpartyRefundStatus);
				expectUserRefundFundDetailPo.setThirdpartyDiscount(BigDecimal.ZERO);
				expectUserRefundFundDetailPo.setRetryTimes(0);
				expectUserRefundFundDetailPo.setMemo("0");

				RefundService.verifyUserRefundFundDetailDb(
						expectUserRefundFundDetailPo, userRefundFundDetailPo);
			}

			BigDecimal totalCard = BigDecimal.ZERO;

			for (SalesRefundInfoVo refundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				totalCard = PrepaidCardService.getCardEntry(userId.intValue(),
						refundInfoVo.getRefundBillNo()).add(totalCard);
			}

			DataUtil.verifyDecimalEquals(orderPo.getCardAmount(), totalCard,
					"校验取消订单退回的预付卡金额");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_029() {
		Logger.start(true, "使用了预付卡订单，余额+第三方支付宝组合支付。确认收货前,订单部分退款的金额超过余额支付的部分");
		try {

			TradingServiceResp placeOrderResp = PrepaidCardService
					.placeOrder2(false);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();
			long sellerId = order.getSellerId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			// 用余额支付金额
			BigDecimal useAccountAmount = new BigDecimal(8);
			// 支付订单 余额+支付宝组合支付
			// 13 为 app国际支付宝，15 微信
			String payType = "13";

			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), useAccountAmount,
					placeOrderResp.getTradingId(), payType);

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall(payType,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			// 等待支付网关异步处理
			Thread.sleep(2000);
			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			// 申请退款
			ApplyRefundReq applyRefundReq = RefundService
					.buildStandApplyRefundReq(order);

			applyRefundReq.getSalesRefundInfoList().remove(1);

			applyRefundReq.getSalesRefundInfoList().get(0)
					.setRefundAmount(useAccountAmount.add(BigDecimal.TEN));

			RefundService.applyRefundCall(applyRefundReq);

			salesrefundsuccessReq.setOrderId(orderId);

			salesrefundsuccessReq.setOperatorInfo("autotest");

			for (int i = 0; i < applyRefundReq.getSalesRefundInfoList().size(); i++) {

				SalesRefundInfoVo salesRefundInfoBean = applyRefundReq
						.getSalesRefundInfoList().get(i);

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoBean
						.getRefundBillNo());

				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("退该订单号 %s 第%s件商品", orderId, i + 1));
				salesrefundsuccessCall.callService();

			}

			Logger.verifyEquals("ok", salesrefundsuccessCall.getReturnData(),
					"验证退货退款成功返回");

			Thread.sleep(3000);

			// 订单表(order)
			OrderPo orderPo = orderShardingWapper.selectOrderbyOrderId(orderId);
			BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
			BigDecimal cardPaidAmount = orderPo.getCardAmount();
			BigDecimal refundedAccountAmount = BigDecimal.ZERO;

			BigDecimal accountAmount = BigDecimal.ZERO;
			BigDecimal thirdpartyAmount = BigDecimal.ZERO;
			BigDecimal cardAmount = BigDecimal.ZERO;

			// 已退款的预付卡金额
			BigDecimal refundedCardAmount = BigDecimal.ZERO;

			// 数据库验证
			for (int j = 0; j < applyRefundReq.getSalesRefundInfoList().size(); j++) {

				SalesRefundInfoVo refund = applyRefundReq
						.getSalesRefundInfoList().get(j);

				String refundBillNo = refund.getRefundBillNo();

				RefundBillPo actualRefundBillPo = orderShardingWapper
						.selectRefundBillByBillNo(refundBillNo);
				
				OrderDetailPo orderDetailPo = orderShardingWapper
						.selectOrderDetailbyOrderIdAndCatalogId(orderId,
								refund.getCatalogId());

				cardAmount = actualRefundBillPo.getCardAmount();
				
				//退款，优先退 预付卡
				if (Utils.isBiggerThanOrEqual(
						cardPaidAmount.subtract(refundedCardAmount),
						refund.getRefundAmount()))
					cardAmount = refund.getRefundAmount();
				else
					cardAmount = cardPaidAmount.subtract(refundedCardAmount);
				
				refundedCardAmount = refundedCardAmount.add(cardAmount);

				//退款减去 退 预付卡
				BigDecimal refundAmount = refund.getRefundAmount().subtract(
						cardAmount);
				
				//余额支付大于退款金额，先退余额
				if (Utils.isBiggerThanOrEqual(
						accountPaidAmount.subtract(refundedAccountAmount),
						refundAmount)) {

					accountAmount = refundAmount;
				} else {

					accountAmount = accountPaidAmount
							.subtract(refundedAccountAmount);
					thirdpartyAmount = refundAmount.subtract(accountAmount);
				}
				
				refundedAccountAmount = refundedAccountAmount.add(accountAmount);
				
				RefundBillPo expectedRefundBillPo = new RefundBillPo();
				BigDecimal freight = orderDetailPo.getFreight();
				
				BigDecimal totalProductPrice = orderDetailPo
						.getProductPrice()
						.multiply(
								new BigDecimal(orderDetailPo.getProductCount()))
						.add(freight);
				
				Logger.comment("totalProductPrice: " + String.valueOf(totalProductPrice) + " RefundAmount: " + String.valueOf(refund
						.getRefundAmount()));
				
				expectedRefundBillPo.setFreight(totalProductPrice.compareTo(refund
						.getRefundAmount()) == 0 ? freight : BigDecimal.ZERO);
				expectedRefundBillPo.setOrderId(orderId);
				expectedRefundBillPo.setSellerId(orderPo.getSellerId());
				expectedRefundBillPo.setUserId(orderPo.getUserId());
				expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
				expectedRefundBillPo.setProductCount(refund.getRefundProductNum());
				expectedRefundBillPo.setAccountAmount(accountAmount);
				expectedRefundBillPo.setCardAmount(cardAmount);
				expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
				expectedRefundBillPo.setRefundBillNo(refundBillNo);
				expectedRefundBillPo.setCatalogId(refund.getCatalogId());
				expectedRefundBillPo.setTotalAmount(refund
						.getRefundAmount());
				expectedRefundBillPo.setTopspeedRefund(false);
				expectedRefundBillPo.setAfterReceiving(false);
				expectedRefundBillPo.setRefundStatus(1);
				expectedRefundBillPo.setDeductedCouponAmount(BigDecimal.ZERO);
				expectedRefundBillPo.setNoSettlementCouponAmount(BigDecimal.ZERO);
				expectedRefundBillPo.setRefundBillStatus(10);
				
				RefundService.verifyRefundBillDb(expectedRefundBillPo,
						actualRefundBillPo);

				DataUtil.verifyDecimalEquals(cardAmount, PrepaidCardService
						.getCardEntry(userId.intValue(), applyRefundReq
								.getSalesRefundInfoList().get(j)
								.getRefundBillNo()), "校验退回的预付卡金额");
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_030() {
		Logger.start(true, "使用了预付卡订单，余额+第三方支付宝组合支付。确认收货前,订单部分退款的金额小于余额支付的部分");
		try {

			TradingServiceResp placeOrderResp = PrepaidCardService
					.placeOrder2(false);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();
			long sellerId = order.getSellerId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			// 用余额支付金额
			BigDecimal useAccountAmount = new BigDecimal(47);
			// 支付订单 余额+支付宝组合支付
			// 13 为 app国际支付宝，15 微信
			String payType = "13";

			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), useAccountAmount,
					placeOrderResp.getTradingId(), payType);

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall(payType,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			// 等待支付网关异步处理
			Thread.sleep(2000);
			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			// 申请退款
			ApplyRefundReq applyRefundReq = RefundService
					.buildStandApplyRefundReq(order);

			applyRefundReq.getSalesRefundInfoList().remove(1);
			applyRefundReq.getSalesRefundInfoList().remove(1);

			applyRefundReq
					.getSalesRefundInfoList()
					.get(0)
					.setRefundAmount(
							useAccountAmount.subtract(new BigDecimal(14)));

			RefundService.applyRefundCall(applyRefundReq);

			salesrefundsuccessReq.setOrderId(orderId);

			salesrefundsuccessReq.setOperatorInfo("autotest");

			for (int i = 0; i < applyRefundReq.getSalesRefundInfoList().size(); i++) {

				SalesRefundInfoVo salesRefundInfoBean = applyRefundReq
						.getSalesRefundInfoList().get(i);

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoBean
						.getRefundBillNo());

				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("退该订单号 %s 第%s件商品", orderId, i + 1));
				salesrefundsuccessCall.callService();

			}

			Logger.verifyEquals("ok", salesrefundsuccessCall.getReturnData(),
					"验证退货退款成功返回");

			Thread.sleep(3000);

			// 订单表(order)
			OrderPo orderPo = orderShardingWapper.selectOrderbyOrderId(orderId);
			BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
			BigDecimal cardPaidAmount = orderPo.getCardAmount();
			BigDecimal refundedAccountAmount = BigDecimal.ZERO;

			BigDecimal accountAmount = BigDecimal.ZERO;
			BigDecimal thirdpartyAmount = BigDecimal.ZERO;
			BigDecimal cardAmount = BigDecimal.ZERO;

			// 已退款的预付卡金额
			BigDecimal refundedCardAmount = BigDecimal.ZERO;

			// 数据库验证
			for (int j = 0; j < applyRefundReq.getSalesRefundInfoList().size(); j++) {

				SalesRefundInfoVo refund = applyRefundReq
						.getSalesRefundInfoList().get(j);

				String refundBillNo = refund.getRefundBillNo();

				RefundBillPo actualRefundBillPo = orderShardingWapper
						.selectRefundBillByBillNo(refundBillNo);
				
				OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);

				cardAmount = actualRefundBillPo.getCardAmount();
				
				//退款，优先退 预付卡
				if (Utils.isBiggerThanOrEqual(
						cardPaidAmount.subtract(refundedCardAmount),
						refund.getRefundAmount()))
					cardAmount = refund.getRefundAmount();
				else
					cardAmount = cardPaidAmount.subtract(refundedCardAmount);
				
				refundedCardAmount = refundedCardAmount.add(cardAmount);

				//退款减去 退 预付卡
				BigDecimal refundAmount = refund.getRefundAmount().subtract(
						cardAmount);
				
				//余额支付大于退款金额，先退余额
				if (Utils.isBiggerThanOrEqual(
						accountPaidAmount.subtract(refundedAccountAmount),
						refundAmount)) {

					accountAmount = refundAmount;
				} else {

					accountAmount = accountPaidAmount
							.subtract(refundedAccountAmount);
					thirdpartyAmount = refundAmount.subtract(accountAmount);
				}
				
				refundedAccountAmount = refundedAccountAmount.add(accountAmount);
				
				RefundBillPo expectedRefundBillPo = new RefundBillPo();

				expectedRefundBillPo.setFreight(BigDecimal.ZERO);
				expectedRefundBillPo.setOrderId(orderId);
				expectedRefundBillPo.setSellerId(orderPo.getSellerId());
				expectedRefundBillPo.setUserId(orderPo.getUserId());
				expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
				expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
				expectedRefundBillPo.setAccountAmount(accountAmount);
				expectedRefundBillPo.setCardAmount(cardAmount);
				expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
				expectedRefundBillPo.setRefundBillNo(refundBillNo);
				expectedRefundBillPo.setCatalogId(refund.getCatalogId());
				expectedRefundBillPo.setTotalAmount(refund
						.getRefundAmount());
				expectedRefundBillPo.setTopspeedRefund(false);
				expectedRefundBillPo.setAfterReceiving(false);
				expectedRefundBillPo.setRefundStatus(1);
				expectedRefundBillPo.setDeductedCouponAmount(BigDecimal.ZERO);
				expectedRefundBillPo.setNoSettlementCouponAmount(BigDecimal.ZERO);
				expectedRefundBillPo.setRefundBillStatus(10);

				RefundService.verifyRefundBillDb(expectedRefundBillPo,
						actualRefundBillPo);

				DataUtil.verifyDecimalEquals(cardAmount, PrepaidCardService
						.getCardEntry(userId.intValue(), applyRefundReq
								.getSalesRefundInfoList().get(0)
								.getRefundBillNo()), "校验退回的预付卡金额");
			}

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_031() {
		Logger.start(true, "下单使用 含有平台优惠的商品 校验平台优惠金额按比例退");
		try {

			TradingServiceResp placeOrderResp = placeOrder3();

			Order order = placeOrderResp.getOrderList().get(0);

			Long orderId = order.getOrderId();

			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);

			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;
			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			Thread.sleep(5000);

			BigDecimal tempNoSettlementCouponAmount = BigDecimal.ZERO;
			

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {

				// 订单表(order)
				OrderPo orderPo = orderShardingWapper.selectOrderbyOrderId(orderId);
				BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
				BigDecimal cardPaidAmount = orderPo.getCardAmount();
				BigDecimal refundedAccountAmount = BigDecimal.ZERO;

				BigDecimal accountAmount = BigDecimal.ZERO;
				BigDecimal thirdpartyAmount = BigDecimal.ZERO;
				BigDecimal cardAmount = BigDecimal.ZERO;

				// 已退款的预付卡金额
				BigDecimal refundedCardAmount = BigDecimal.ZERO;
				
				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);
					
					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);

					cardAmount = actualRefundBillPo.getCardAmount();
					
					//退款，优先退 预付卡
					if (Utils.isBiggerThanOrEqual(
							cardPaidAmount.subtract(refundedCardAmount),
							refund.getRefundAmount()))
						cardAmount = refund.getRefundAmount();
					else
						cardAmount = cardPaidAmount.subtract(refundedCardAmount);
					
					refundedCardAmount = refundedCardAmount.add(cardAmount);

					//退款减去 退 预付卡
					BigDecimal refundAmount = refund.getRefundAmount().subtract(
							cardAmount);
					
					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							refundAmount)) {

						accountAmount = refundAmount;
					} else {

						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
						thirdpartyAmount = refundAmount.subtract(accountAmount);
					}
					
					refundedAccountAmount = refundedAccountAmount.add(accountAmount);
					
					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(orderPo.getUserId());
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(cardAmount);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(1);
					expectedRefundBillPo.setDeductedCouponAmount(BigDecimal.ZERO);
					BigDecimal noSettlementCouponAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						noSettlementCouponAmount = orderPo
								.getYmtCouponAmount()
								.subtract(tempNoSettlementCouponAmount);
					}

					else {
						noSettlementCouponAmount = RefundService
								.devideThenMultiply(refund.getRefundAmount(),
										order.getOrderPayableAmount().add(orderPo.getCardAmount()), Utils
												.zeroIfNull(orderPo
														.getYmtCouponAmount()));

						tempNoSettlementCouponAmount = tempNoSettlementCouponAmount
								.add(noSettlementCouponAmount);
					}

					expectedRefundBillPo
							.setNoSettlementCouponAmount(noSettlementCouponAmount);

					expectedRefundBillPo.setRefundBillStatus(10);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);
				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_032() {
		Logger.start(true, "下单使用 返点金额 ，确认收货前，全部退货退款，校验返点金额按比例退");
		try {

			TradingServiceResp placeOrderResp = TradingCallService
					.placeAnlihuiOrder(BigDecimal.TEN, false, 0);
			
			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getTradingId();

			BigDecimal useAccountAmount = placeOrderResp.getPayableAmount();

			TradingCallService.payOrder(userId, useAccountAmount, tradingId);

			Order order = placeOrderResp.getOrderList().get(0);

			Long orderId = order.getOrderId();

			//接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);

			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			salesrefundsuccessReq.setOperatorInfo("autotest");
			salesrefundsuccessReq.setOrderId(orderId);

			int i = 0;
			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("ok",
						salesrefundsuccessCall.getReturnData(), "验证退货退款成功返回");
				i++;
			}

			Thread.sleep(5000);

			BigDecimal tempNoSettlementCouponAmount = BigDecimal.ZERO;
			

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {

				// 订单表(order)
				OrderPo orderPo = orderShardingWapper.selectOrderbyOrderId(orderId);
				BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
				BigDecimal cardPaidAmount = orderPo.getCardAmount();
				BigDecimal refundedAccountAmount = BigDecimal.ZERO;

				BigDecimal accountAmount = BigDecimal.ZERO;
				BigDecimal thirdpartyAmount = BigDecimal.ZERO;
				BigDecimal cardAmount = BigDecimal.ZERO;

				// 已退款的预付卡金额
				BigDecimal refundedCardAmount = BigDecimal.ZERO;
				
				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);
					
					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);

					cardAmount = Utils.zeroIfNull(actualRefundBillPo.getCardAmount());
					
					BigDecimal refundRebateAmount = RefundService
							.apportionRefundRebate(orderDetailPo,
									refund.getRefundAmount());
							
					//退款，优先退 预付卡
					if (Utils.isBiggerThanOrEqual(
							cardPaidAmount.subtract(refundedCardAmount),
							refund.getRefundAmount()))
						cardAmount = refund.getRefundAmount();
					else
						cardAmount = cardPaidAmount.subtract(refundedCardAmount);
					
					refundedCardAmount = refundedCardAmount.add(cardAmount);

					//退款减去 退 预付卡
					BigDecimal refundAmount = refund.getRefundAmount().subtract(
							cardAmount);
					
					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							refundAmount)) {

						accountAmount = refundAmount;
					} else {

						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
						thirdpartyAmount = refundAmount.subtract(accountAmount);
					}
					
					refundedAccountAmount = refundedAccountAmount.add(accountAmount);
					
					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setFreight(orderDetailPo.getFreight());
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(orderPo.getUserId());
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(cardAmount);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(1);
					expectedRefundBillPo.setDeductedCouponAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setRebateAmount(refundRebateAmount);
					
					BigDecimal noSettlementCouponAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						noSettlementCouponAmount = orderPo
								.getYmtCouponAmount()
								.subtract(tempNoSettlementCouponAmount);
					}

					else {
						noSettlementCouponAmount = RefundService
								.devideThenMultiply(refund.getRefundAmount(),
										order.getOrderPayableAmount().add(orderPo.getCardAmount()), Utils
												.zeroIfNull(orderPo
														.getYmtCouponAmount()));

						tempNoSettlementCouponAmount = tempNoSettlementCouponAmount
								.add(noSettlementCouponAmount);
					}

					expectedRefundBillPo
							.setNoSettlementCouponAmount(noSettlementCouponAmount);

					expectedRefundBillPo.setRefundBillStatus(10);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);
				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SalesRefundSuccess_033() {
		Logger.start(true, "下单使用 返点金额 ，确认收货前，退款金额小于可支付金额，校验返点金额按比例退");
		try {

			TradingServiceResp placeOrderResp = TradingCallService
					.placeAnlihuiOrder(BigDecimal.TEN, false, 0);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();
			long sellerId = order.getSellerId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			// 用余额支付金额
			BigDecimal useAccountAmount = new BigDecimal(47);
			// 支付订单 余额+支付宝组合支付
			// 13 为 app国际支付宝，15 微信
			String payType = "13";

			Long thirdTradingId = TradingCallService.payOrder(
					placeOrderResp.getUserId(), useAccountAmount,
					placeOrderResp.getTradingId(), payType);

			// 支付网关支付回调交易
			SQPayGateWayCallService.notifyCall(payType,
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			// 等待支付网关异步处理
			Thread.sleep(2000);
			
			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			// 申请退款
			ApplyRefundReq applyRefundReq = RefundService
					.buildStandApplyRefundReq(order);

			applyRefundReq
					.getSalesRefundInfoList()
					.get(0)
					.setRefundAmount(
							useAccountAmount.subtract(new BigDecimal(14)));

			RefundService.applyRefundCall(applyRefundReq);

			salesrefundsuccessReq.setOrderId(orderId);

			salesrefundsuccessReq.setOperatorInfo("autotest");

			for (int i = 0; i < applyRefundReq.getSalesRefundInfoList().size(); i++) {

				SalesRefundInfoVo salesRefundInfoBean = applyRefundReq
						.getSalesRefundInfoList().get(i);

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoBean
						.getRefundBillNo());

				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("退该订单号 %s 第%s件商品", orderId, i + 1));
				salesrefundsuccessCall.callService();

			}
			
			Thread.sleep(5000);

			if (salesrefundsuccessCall.getReturnData().equals("ok")) {

				// 订单表(order)
				OrderPo orderPo = orderShardingWapper.selectOrderbyOrderId(orderId);
				BigDecimal accountPaidAmount = orderPo.getAccountPaidAmount();
				BigDecimal cardPaidAmount = orderPo.getCardAmount();
				BigDecimal refundedAccountAmount = BigDecimal.ZERO;

				BigDecimal accountAmount = BigDecimal.ZERO;
				BigDecimal thirdpartyAmount = BigDecimal.ZERO;
				BigDecimal cardAmount = BigDecimal.ZERO;
				BigDecimal tempNoSettlementCouponAmount = BigDecimal.ZERO;

				// 已退款的预付卡金额
				BigDecimal refundedCardAmount = BigDecimal.ZERO;
				
				// 数据库验证
				for (int j = 0; j < applyRefundReq.getSalesRefundInfoList()
						.size(); j++) {

					SalesRefundInfoVo refund = applyRefundReq
							.getSalesRefundInfoList().get(j);

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);
					
					OrderDetailPo orderDetailPo = orderShardingWapper.selectOrderDetailbyOrderId(orderId).get(j);

					cardAmount = actualRefundBillPo.getCardAmount();
					
					BigDecimal refundRebateAmount = RefundService
							.apportionRefundRebate(orderDetailPo,
									refund.getRefundAmount());
					
					//退款，优先退 预付卡
					if (Utils.isBiggerThanOrEqual(
							cardPaidAmount.subtract(refundedCardAmount),
							refund.getRefundAmount()))
						cardAmount = refund.getRefundAmount();
					else
						cardAmount = cardPaidAmount.subtract(refundedCardAmount);
					
					refundedCardAmount = refundedCardAmount.add(cardAmount);

					//退款减去 退 预付卡
					BigDecimal refundAmount = refund.getRefundAmount().subtract(
							cardAmount);
					
					//余额支付大于退款金额，先退余额
					if (Utils.isBiggerThanOrEqual(
							accountPaidAmount.subtract(refundedAccountAmount),
							refundAmount)) {

						accountAmount = refundAmount;
					} else {

						accountAmount = accountPaidAmount
								.subtract(refundedAccountAmount);
						thirdpartyAmount = refundAmount.subtract(accountAmount);
					}
					
					refundedAccountAmount = refundedAccountAmount.add(accountAmount);
					
					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setFreight(RefundService
							.apportionFreight(orderDetailPo,
									refund.getRefundAmount(),
									refund.getRefundProductNum()));
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setSellerId(orderPo.getSellerId());
					expectedRefundBillPo.setUserId(orderPo.getUserId());
					expectedRefundBillPo.setThirdpartyDiscount(BigDecimal.ZERO);
					expectedRefundBillPo.setProductCount(orderDetailPo.getProductCount());
					expectedRefundBillPo.setAccountAmount(accountAmount);
					expectedRefundBillPo.setCardAmount(cardAmount);
					expectedRefundBillPo.setThirdpartyAmount(thirdpartyAmount);
					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(1);
					expectedRefundBillPo.setDeductedCouponAmount(BigDecimal.ZERO);
					expectedRefundBillPo.setRebateAmount(refundRebateAmount);
					
					BigDecimal noSettlementCouponAmount = BigDecimal.ZERO;

					if (j == applyRefundReq.getSalesRefundInfoList().size() - 1) {

						noSettlementCouponAmount = orderPo
								.getYmtCouponAmount()
								.subtract(tempNoSettlementCouponAmount);
					}

					else {
						noSettlementCouponAmount = RefundService
								.devideThenMultiply(refund.getRefundAmount(),
										order.getOrderPayableAmount().add(orderPo.getCardAmount()), Utils
												.zeroIfNull(orderPo
														.getYmtCouponAmount()));

						tempNoSettlementCouponAmount = tempNoSettlementCouponAmount
								.add(noSettlementCouponAmount);
					}

					expectedRefundBillPo
							.setNoSettlementCouponAmount(noSettlementCouponAmount);

					expectedRefundBillPo.setRefundBillStatus(10);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);
				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}
